// $Id: example.h 16 2008-10-07 23:45:24Z rodlima $

#include <object.h>
#include <relations.h>
#include <config.h>
#include <boost/date_time/gregorian/gregorian.hpp>

struct Class;
struct Student;
struct Relative;
struct Evaluation;
struct Grade;
struct PlannedEvaluation;

struct Discipline : orm::object<Discipline>/*{{{*/
{
    static orm::metainfo<Discipline> meta;

    Discipline(const std::string &_name="", bool en=true)
        : name(_name), enabled(en)
        , classes(*this) {}

#ifdef HAS_DEFAULTED_MOVE_CTOR
    Discipline(Discipline &&that) = default;
#else
    Discipline(Discipline &&that) 
        : orm::object<Discipline>(std::move(that))
        , name(std::move(that.name))
        , enabled(that.enabled)
        , priority(that.priority)
        , creation(std::move(that.creation))
        , altname(std::move(that.altname))
        , classes(std::move(that.classes)) {}
#endif

    std::string name;
    bool enabled;
    boost::optional<int> priority;
    boost::gregorian::date creation;
    boost::optional<std::string> altname;
    orm::rel<Class,0,orm::MANY> classes;
};/*}}}*/

struct Class : orm::object<Class>/*{{{*/
{
    static orm::metainfo<Class> meta;

    Class(const std::string &_name="")
        : name(_name)
        , discipline(*this) , students(*this) , planned_evaluations(*this) {}

#ifdef HAS_DEFAULTED_MOVE_CTOR
    Class(Class &&that) = default;
#else
    Class(Class &&that) 
        : orm::object<Class>(std::move(that))
        , name(std::move(that.name))
        , discipline(std::move(that.discipline))
        , students(std::move(that.students))
        , planned_evaluations(std::move(that.planned_evaluations)) {}
#endif

    std::string name;
    orm::rel<Discipline,1,1> discipline;
    orm::rel<Student,0,orm::MANY,orm::MASTER> students;
    orm::rel<PlannedEvaluation,0,orm::MANY> planned_evaluations;
};/*}}}*/

struct Address : orm::object<Address>/*{{{*/
{
    static orm::metainfo<Address> meta;
    Address(const std::string &_end="")
        : street(_end)
        , student(*this) {}

#ifdef HAS_DEFAULTED_MOVE_CTOR
    Address(Address &&that) = default;
#else
    Address(Address &&that)
        : orm::object<Address>(std::move(that))
        , street(std::move(that.street))
        , student(std::move(that.student)) {}
#endif

    std::string street;
    orm::rel<Student,1,1> student;
};/*}}}*/

struct Student : orm::object<Student>/*{{{*/
{
    static orm::metainfo<Student> meta;

    Student(const std::string &_name="")
        : name(_name)
        , classes(*this), father(*this), mother(*this), address(*this)
        , aunts(*this), uncles(*this) {}

#ifdef HAS_DEFAULTED_MOVE_CTOR
    Student(Student &&that) = default;
#else
    Student(Student &&that) 
        : orm::object<Student>(std::move(that))
        , name(std::move(that.name))
        , classes(std::move(that.classes))
        , father(std::move(that.father))
        , mother(std::move(that.mother))
        , address(std::move(that.address))
        , aunts(std::move(that.aunts))
        , uncles(std::move(that.uncles)) {}
#endif

    std::string name;
    orm::rel<Class,0,orm::MANY> classes;

    orm::rel<Relative,0,1> father;
    orm::rel<Relative,0,1> mother;
    orm::rel<Address,1,1,orm::MASTER> address;

    orm::rel<Relative,0,orm::MANY> aunts;
    orm::rel<Relative,0,orm::MANY> uncles;
};/*}}}*/

struct Relative : orm::object<Relative>/*{{{*/
{
    static orm::metainfo<Relative> meta;

    Relative(const std::string &_name="") 
        : name(_name)
        , children(*this) {}

#ifdef HAS_DEFAULTED_MOVE_CTOR
    Relative(Relative &&that) = default;
#else
    Relative(Relative &&that) 
        : orm::object<Relative>(std::move(that))
        , children(std::move(that.children)) {}
#endif

    std::string name;
    orm::const_rel<Student,0,orm::MANY> children;
};/*}}}*/

struct PlannedEvaluation : orm::object<PlannedEvaluation>/*{{{*/
{
    static orm::metainfo<PlannedEvaluation> meta;

    PlannedEvaluation()
        : class_(*this), evaluation(*this) {}

#ifdef HAS_DEFAULTED_MOVE_CTOR
    PlannedEvaluation(PlannedEvaluation &&that) = default;
#else
    PlannedEvaluation(PlannedEvaluation &&that) 
        : orm::object<PlannedEvaluation>(std::move(that))
        , class_(std::move(that.class_))
        , evaluation(std::move(that.evaluation))
        , date(std::move(that.date)) {}
#endif

    orm::rel<Class,1,1> class_;
    orm::rel<Evaluation,0,1> evaluation;

    boost::optional<boost::gregorian::date> date;
};/*}}}*/

struct Evaluation : orm::object<Evaluation>/*{{{*/
{
    static orm::metainfo<Evaluation> meta;

    Evaluation()
        : planned_evaluation(*this), grades(*this) {}
#ifdef HAS_DEFAULTED_MOVE_CTOR
    Evaluation(Evaluation &&that) = default;
#else
    Evaluation(Evaluation &&that) 
        : orm::object<Evaluation>(std::move(that))
        , planned_evaluation(std::move(that.planned_evaluation))
        , grades(std::move(that.grades))
        , date(std::move(that.date)) {}
#endif

    orm::rel<PlannedEvaluation,1,1> planned_evaluation;
    orm::rel<Grade,1,orm::MANY> grades;

    boost::gregorian::date date;
};/*}}}*/

struct Grade : orm::object<Grade>/*{{{*/
{
    static orm::metainfo<Grade> meta;

    Grade(double _grade=0)
        : student(*this), evaluation(*this)
        , value(_grade) {}
#ifdef HAS_DEFAULTED_MOVE_CTOR
    Grade(Grade &&that) = default;
#else
    Grade(Grade &&that) 
        : orm::object<Grade>(std::move(that))
        , student(std::move(that.student))
        , evaluation(std::move(that.evaluation))
        , value(that.value) {}
#endif

    orm::rel<Student,1,1> student;
    orm::rel<Evaluation,1,1> evaluation;

    double value;
};/*}}}*/

